<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/8/8
 * Time: 11:08
 */
class PushService
{
    private $jpushSetModel;
    private $userService;

    function __construct()
    {
        $this->jpushSetModel        = new JpushSetModel();
        $this->userService          = new UserService();
    }

    /**
     * 推送的key管理
     * @return mixed
     */
    private function getPushKey($platform, $partner = 'baidu')
    {
        $conf = array(
            'baidu' => array(
                'android'   =>  array('qAneZ14WaxH1LsRvLadleD4K', 'Y90K5P39bKcnRqwt7o6P45ioU7ELMboL'),//apiKey secretKey
                'ios'       =>  array('55eRZyxQ1uNpMbt9ydU1SxZS', 'Yr9GB28CEf54m05z1369Yp9nT5A3WmH2')//apiKey secretKey
            )
        );
        if (in_array($partner, $conf)) return false;

        return $conf[$partner][$platform];
    }

    /**
     * 获取用户推送信息
     * @param $uid
     * @return array|object
     */
    public function getPushInfo($uid)
    {
        // 1.获取源数据
        $info   = $this->getPushInfoFromCacheOrMysql($uid);

        // 2.组装返回数据
        return $this->pushInfoData($info);
    }

    /**
     * 从缓存或数据库获取推送信息
     * @param $uid
     * @return Array|bool
     */
    private function getPushInfoFromCacheOrMysql($uid)
    {
        return $this->jpushSetModel->getPushInfo(array('uid' => $uid));
    }

    /**
     * 根据业务逻辑组装推送返回数据结构
     * @param $info
     * @return array
     */
    private function pushInfoData($info)
    {
        if (empty($info)) return array();

        $result = array(
            'uid'               =>  $info['uid'],
            'deviceSN'          =>  $info['deviceSN'],
            'control'           =>  $info['master_control'],
            'disturb'           =>  $info['dnd_set'],
            'sound_show'        =>  $info['sound_show'],
            'content_show'      =>  $info['content_show'],
            'commentPush'       =>  $info['commentPush'],
            'messagePush'       =>  $info['messagePush'],
            'followPush'        =>  $info['followPush'],
            'startHour'         =>  $info['startHour'] ? $info['startHour'] : AC::START_HOUR,
            'endHour'           =>  $info['endHour'] ? $info['endHour'] : AC::END_HOUR,
            'extra'             =>  $info['jpush_extra'] ? json_decode($info['jpush_extra'], true) : (Object) array()
        );

        return $result;
    }

    /**
     * php client 将推送信息存放到redis中去
     * @param $info
     * @param $action
     * @param $host_uid
     * @return bool
     */
    public function pushToRedisList($info, $action, $toUid, $host_uid)
    {
        // 1.获取用户推送设置
        $pushInfo = $this->getPushInfo($toUid);
        if (empty($pushInfo)) return false;

        // 2.组装传入的推送数据结构
        $formatInfo = $this->formatPushData($info, $action, $pushInfo, $host_uid);

        // 3.run push
        $this->runPush($formatInfo, $pushInfo);

        return true;
    }

    public function pushToTag($info){
        $data = array(
            'content'  =>    $info['content'],
            'extras'   =>    array(
                'uid'      =>  $info['uid'],
                'nickname' =>  $info['nickname'],
                'gid'      =>  $info['gid'],
                'name'     =>  $info['name'],
                'type'     =>  6,
                'time'     =>  AC::SERVER_TIME,
            )
        );

        $data['content'] = Emotion::emotionToCharacter($data['content']);
        list($apiKey, $secretKey)   =  $this->getPushKey('ios');
        Jpush::baiduTagPush($data, $apiKey, $secretKey);

        return true;
    }

    private function formatPushData($info, $action, $pushInfo, $host_uid)
    {
        $actions    =   $this->getPushActions($info);

        // 1.不对用户自己推送
        if (!$host_uid || $host_uid == $actions[$action]['uid']){
            return false;
        }

        // 2.判断用户推送设置
        $check  =	$this->checkPushSet($pushInfo, $actions[$action]['push_type']);
        if (!$check) return false;

        return $this->getPushFormatData($actions[$action], $info, $pushInfo);
    }

    /**
     * 计算推送数据
     * @param $uid
     * @return int
     */
    private function countPushBadges($uid)
    {
        $statics    =   $this->userService->getUserStatisticsDetail($uid);
        if ($statics)
        {
            return intval($statics['newTopicComment'] + $statics['newLikeMeTimes'] + $statics['messageTimes'] + $statics['newAnnounceTimes']);
        }

        return 1;
    }

    private function getPushActions($info)
    {
        return array(
            "pushMessage"	=>	array(
                'uid'	    =>	$info['mUid'],
                'push_type'	=>	1,
                'count'		=>	'messageTimes',
                'action'	=>	'message'
            ),
            "pushFollow"	=>	array(
                'uid'	    =>	$info['fUid'],
                'push_type'	=>	2,
                'count'		=>	'newFollowTimes',
                'action'	=>	'follow'
            ),
            "pushComment"	=>	array(
                'uid'	    =>	isset($info['parentId']) && intval($info['parentId'])>0 ? $info['rUid'] : $info['cUid'],
                'push_type'	=>	4,
                'count'		=>	"newCommentTimes",
                'action'	=>	'comment'
            ),
            "pushTopicComment"	=>	array(
                'uid'	    =>	isset($info['parentId']) && intval($info['parentId'])>0 ? $info['rUid'] : $info['author_uid'],
                'push_type'	=>	4,
                'count'		=>	"newTopicComment",
                'action'	=>	'topicComment'
            ),
            "pushAnonymousComment"	=>	array(
                'uid'	    =>	isset($info['parentId']) && intval($info['parentId'])>0 ? $info['rUid'] : $info['author_uid'],
                'push_type'	=>	4,
                'count'		=>	"newCommentTimes",
                'action'	=>	'anonymousComment'
            )
        );
    }

    private function getPushFormatData($actionInfo, $info, $pushInfo)
    {
        list($user_id, $deviceSN, $OS, $platform, $apiKey, $secretKey) = $this->buildRunPushParams($pushInfo);
        $info[$actionInfo['count']] = $this->countPushBadges($actionInfo['uid']);

        $ac = $actionInfo['action'].'PushData';
        $formatData = $this->$ac($info, $OS, $pushInfo['content_show']);
        if (!empty($formatData['content'])){
            $formatData['content'] = Emotion::emotionToCharacter($formatData['content']);
        }

        return $formatData;
    }

    private function checkPushSet($pushInfo, $type)
    {
        if ($pushInfo['control'] || empty($pushInfo['deviceSN'])) return false;

        $time		=	intval(date("H",AC::SERVER_TIME));
        if ($pushInfo['disturb'] == 0 && $pushInfo['startHour'] > $pushInfo['endHour'])
        {
            if (($time >= $pushInfo['startHour'] && $time < 24) || ($time >= 0 && $time < $pushInfo['endHour'])) return false;
        }

        if ($pushInfo['disturb'] == 0 && $pushInfo['startHour'] < $pushInfo['endHour'])
        {
            if ($time >= $pushInfo['startHour'] && $time < $pushInfo['endHour']) return false;
        }

        if ($pushInfo['messagePush']  && $type == 1) 	return false;
        if ($pushInfo['followPush']   && $type == 2) 	return false;
        if ($pushInfo['commentPush']  && $type == 4) 	return false;

        return $pushInfo;
    }

    /**
     * 执行推送
     * @param $formatInfo
     * @param $pushInfo
     * @return bool
     */
    private function runPush($formatInfo, $pushInfo)
    {
        if (empty($formatInfo) || empty($pushInfo)) return false;

        list($user_id, $deviceSN, $OS, $platform, $apiKey, $secretKey) = $this->buildRunPushParams($pushInfo);
        if (empty($user_id)) return false;

        if ($OS == 1){
            Jpush::baiduPushAnd($formatInfo, $user_id, $deviceSN);
        }else{
            Jpush::baiduPushIos($formatInfo, $user_id, $deviceSN, $apiKey, $secretKey, $platform);
        }
        
        return true;
    }

    private function buildRunPushParams($pushInfo)
    {
        $pushInfo['extra']          =  (array)$pushInfo['extra'];
        $user_id                    =  $pushInfo['extra']['baidu_push_info']['baidu_user_id'];
        $deviceSN                   =  substr($pushInfo['deviceSN'], 0, 5);
        list($OS, $platform)        =  UK::getOsAndPlantform($pushInfo['extra']);
        list($apiKey, $secretKey)   =  $this->getPushKey('ios');

        return array($user_id, $deviceSN, $OS, $platform, $apiKey, $secretKey);
    }

    private function messagePushData($info, $OS, $content)
    {
        // 获取备注名
        $uid = $info['mUid'];
        $nickname = $this->userService->getUserRemark($info['uid'], $info['nickname'], $uid);
        $eventTypeGid = 0;


        $data['content'] = $info['content'];
        $data['data'] 	 = array(
            'uid' 	 	=>  $uid,
            'nickname'	=>	$info['mNickname'],
            'fromUid'	=>	$info['uid'],
            'fNickname'	=>	$nickname,
            'time'		=>	AC::SERVER_TIME,
            'type'		=>	1,
            'eventType' 	=>  	$info['eventType'],
            'eventTypeGid'  =>  	$info['eventTypeGid'],
            'messageTimes'	=>	$info['messageTimes']
        );

        // IOS通知内容
        if ($OS != 1){
            $data['content']	=	$nickname.':'.$info['content'];
            if ($content !=0){
                $data['content'] = "你收到了一条私信";
            }
        }

        return $data;
    }

    private function followPushData($info, $OS, $content)
    {
        // 获取备注名
        $uid = $info['fUid'];
        $nickname = $this->userService->getUserRemark($info['uid'], $info['nickname'], $uid);

        $data['content'] = $nickname.'关注了你';
        $data['data'] 	 = array(
            'uid' 	 	=>  $uid,
            'nickname'	=>	$info['fNickname'],
            'fromUid'	=>	$info['uid'],
            'fNickname'	=>	$nickname,
            'time'		=>	AC::SERVER_TIME,
            'type'		=>	2,
            'newFollowTimes'	=>	$info['newFollowTimes']
        );

        // IOS屏蔽通知内容时的格式
        if ($content !=0 && $OS != 1){
            $data['content'] = "有人关注了你";
        }
        return $data;
    }

    private function commentPushData($info, $OS, $content)
    {
        // 获取备注名
        $uid = isset($info['parentId']) && intval($info['parentId']) > 0 ? $info['rUid'] : $info['cUid'];
        $nickname = $this->userService->getUserRemark($info['uid'], $info['nickname'], $uid);

        $data['content'] = $info['content'];
        $data['data'] 	 = array(
            'uid'		=>	$uid,
            'nickname'	=>	$info['cNickname'],
            'fromUid'	=>	$info['uid'],
            'fNickname'	=>	$nickname,
            'bodyId'	=>	$info['bodyId'],
            'time'		=>	AC::SERVER_TIME,
            'type'		=>	4,
            'newCommentTimes'	=>	$info['newCommentTimes']
        );

        // IOS通知内容
        if ($OS != 1){
            if($info['parentId']>0){
                $data['content'] = $nickname.'回复了你:'.$info['content'];
            }else{
                $data['content'] = $nickname.'评论了你的日记:'.$info['content'];
            }
            if ($content !=0){
                $data['content'] = "有人评论了你的日记";
            }
        }

        return $data;
    }

    private function topicCommentPushData($info, $OS, $content)
    {
        // 获取备注名
        $uid = isset($info['parentId']) && intval($info['parentId']) > 0 ? $info['rUid'] : $info['author_uid'];
        $nickname = $this->userService->getUserRemark($info['uid'], $info['nickname'], $uid);

        $data['content'] = $info['content'];
        $data['data'] 	 = array(
            'uid'		=>	$uid,
            'nickname'	=>	$info['author_name'],
            'fromUid'	=>	$info['uid'],
            'fNickname'	=>	$nickname,
            'tid'		=>	$info['tid'],
            'time'		=>	AC::SERVER_TIME,
            'type'		=>	5,
            'newTopicComment'	=>	$info['newTopicComment']
        );

        // IOS通知内容
        if ($OS != 1){
            $data['content'] = $nickname.'在粉粉圈中评论了你:'.$info['content'];
            if ($content !=0 ){
                $data['content'] = "有人在粉粉圈中评论了你";
            }
        }

        return $data;
    }

    private function anonymousCommentPushData($info, $OS, $content)
    {
        // 获取备注名
        $uid = isset($info['parentId']) && intval($info['parentId']) > 0 ? $info['rUid'] : $info['author_uid'];

        $data['content'] = $info['content'];
        $data['data'] 	 = array(
            'uid'	=>	$uid,// 接受推送的用户
            'fromUid'	=>	$info['uid'],// 谁评论/回复的
            'bodyId'	=>	$info['bodyId'],// 小纸条作者
            'position'  =>  $info['position'],// 该条评论/回复的楼层数
            'time'		=>	AC::SERVER_TIME,
            'type'		=>	6,
            'newAnonymousCommentTimes'	=>	$info['newAnonymousCommentTimes']
        );

        // IOS通知内容
        if ($OS != 1){
            if($info['parentId']>0){
                $data['content'] = '有人回复了你的纸条评论';
            }else{
                $data['content'] = '有人评论了你的小纸条';
            }

            if (empty($content)) $data['content'] .= ':'.$info['content'];
        }

        return $data;
    }
}